﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.Caching.Memory;
using OA.BLL;
using OA.Core.Helper;
using OA.Core.Oss;
using OA.Model;
using OA.Model.Config;
using OA.Model.DB;
using OA.Web.Attribute;
using OA.Web.Code;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace OA.Web.Controllers
{
    [SiteInfo]
    public class BaseController : Controller
    {
        private readonly ICookie _cookie;
        private readonly IMemoryCache _cache;
        private readonly IHttpContextAccessor _httpContextAccessor;
        public BaseConfig BaseConfig { get; set; }
        public OssConfig OssConfig { get; set; }
        public CBase MyBusiness { get; set; }

        /// <summary>
        /// 用户类型 1：用户  2：超级管理员
        /// </summary>
        public int UserType { get; set; }
        public DbContextFactory dbContextFactory { get; set; }

       

        public int UserID { get; set; }

        public string EmpID { get; set; }

        public BaseController(IHttpContextAccessor accessor, ICookie cookie, IMemoryCache cache)
        {
            CallContext.SetData("IHttpContextAccessor", accessor);
            _cookie = cookie;
            _cache = cache;
            _httpContextAccessor = accessor;
            CacheHelper cacheHelper = new CacheHelper(_cache);
            dbContextFactory = new DbContextFactory();
            MyBusiness = new CBase();
            /*从缓存中获取网站基础配置*/
            BaseConfig = cacheHelper.GetConfig<BaseConfig>();
            OssConfig = cacheHelper.GetConfig<OssConfig>();             
          
            string userTypeStr_MM = cookie.GetCookies(CookieHelper.UserID);
            if (!string.IsNullOrWhiteSpace(userTypeStr_MM))
            {
                string userTypeStr = userTypeStr_MM.FromBase62<string>();
                if (string.IsNullOrWhiteSpace(userTypeStr))//解码失败
                {
                    _cookie.DeleteCookies(CookieHelper.UserID);
                    return;
                }                
            }

        }

        public string GetModelStateError(ModelStateDictionary ModelState)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var key in ModelState.Keys)
            {
                var state = ModelState[key];
                if (state.Errors.Any())
                {
                    var errorInfo = state.Errors.First();
                    string ex = (errorInfo.Exception == null ? "" : errorInfo.Exception.ToString());
                    sb.AppendFormat("<p class=\"modelStateError\">{0}:{1}<p>", key, string.IsNullOrEmpty(errorInfo.ErrorMessage) ? ex : errorInfo.ErrorMessage);
                }
            }
            return sb.ToString();          
            
        }

        public string GetError(string msg)
        {
            return string.Format("<p class='modelStateError'>{0}<p>", msg);
        }

        public int AddInfo<T>(T info) where T : BaseInfo
        {
            return dbContextFactory.AddInfo<T>(info);
        }

        public int AddRange<T>(List<T> list) where T : BaseInfo
        {
            return dbContextFactory.AddRange<T>(list);
        }


        public K GetInfo<T, K>(int id, Expression<Func<T, K>> Map) where T : BaseInfo
        {
            return dbContextFactory.GetInfo<T, K>(id, Map);
        }

        public K GetInfo<T, K>(Expression<Func<T, bool>> where, Expression<Func<T, K>> Map) where T : BaseInfo
        {
            return dbContextFactory.GetInfo<T, K>(where, Map);
        }


        public T GetInfo<T>(int id) where T : BaseInfo
        {
            return dbContextFactory.GetInfo<T>(id);
        }

        public T GetInfo<T>(Expression<Func<T, bool>> where) where T : BaseInfo
        {
            return dbContextFactory.GetInfo<T>(where);
        }


        public T GetInfoAsNoTracking<T>(Expression<Func<T, bool>> where) where T : BaseInfo
        {
            return dbContextFactory.GetInfoAsNoTracking<T>(where);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="order"></param>
        /// <param name="sortType">1:顺序 2：倒序</param>
        /// <returns></returns>
        public T GetLastInfo<T>(Expression<Func<T, bool>> where, Expression<Func<T, long>> order, int sortType = 2) where T : BaseInfo
        {
            return dbContextFactory.GetLastInfo<T>(where, order, sortType);
        }

        /// <summary>
        /// 1:顺序 2：倒序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="order"></param>
        /// <param name="sortType"></param>
        /// <returns></returns>
        public T GetLastInfo<T>(Expression<Func<T, bool>> where, Expression<Func<T, string>> order, int sortType = 2) where T : BaseInfo
        {
            return dbContextFactory.GetLastInfo<T>(where, order, sortType);
        }


        public int Delete<T>(long id) where T : BaseInfo
        {
            return dbContextFactory.Delete<T>(id);
        }

        public int Delete<T>(Expression<Func<T, bool>> where) where T : BaseInfo
        {
            return dbContextFactory.Delete<T>(where);
        }


        /// <summary>
        /// 更新对象（需要在查询一次对象）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <param name="t"></param>
        /// <param name="fileds"></param>
        /// <returns></returns>
        public int UpdateByID<T>(long id, T t, string[] fileds) where T : BaseInfo
        {
            return dbContextFactory.Update<T>(id, t, fileds);
        }


        public int UpdateList<T>(List<T> list, string[] fileds) where T : BaseInfo
        {
            return dbContextFactory.Update<T>(list, fileds);
        }

        public int UpdateByWhere<T>(Expression<Func<T, bool>> where, T t, string[] fileds) where T : BaseInfo
        {
            return dbContextFactory.UpdateByWhere<T>(where, t, fileds);
        }



        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <param name="oldInfo"></param>
        /// <param name="t"></param>
        /// <param name="fileds"></param>
        /// <param name="filed2">不需要更新的字段</param>
        /// <returns></returns>
        public int Update<T>(long id, T oldInfo, T t, string[] fileds, string[] filed2) where T : BaseInfo
        {
            return dbContextFactory.Update<T>(oldInfo, t, fileds, filed2);
        }

        public int Update<T>(T oldInfo, T t, string[] fileds, string[] filed2) where T : BaseInfo
        {
            return dbContextFactory.Update<T>(oldInfo, t, fileds, filed2);
        }

        public int UpdateByWhere<T>(Expression<Func<T, bool>> where, T t, string[] fileds, long userID) where T : BaseInfo
        {
            return dbContextFactory.UpdateByWhere<T>(where, t, fileds);
        }

        /// <summary>
        /// 更新对象（不需要在查询一次对象）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <param name="oldInfo"></param>
        /// <param name="t"></param>
        /// <param name="fileds"></param>
        /// <returns></returns>
        public int Update<T>(T oldInfo, T t, string[] fileds) where T : BaseInfo
        {
            return dbContextFactory.Update<T>(oldInfo, t, fileds);
        }

        public int ExecuteSql(string sql, params SqlParameter[] pars)
        {
            return dbContextFactory.ExecuteSql(sql, pars);
        }

        /// <summary>
        /// 执行sql语句 视图 存储过程("dbo.GetDestinationSummary @p0, @p1", country, keyWords);
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="pars"></param>
        /// <returns></returns>
        public List<T> ExecuteQuery<T>(string sql, params SqlParameter[] pars) where T : class, new()
        {
            return dbContextFactory.ExecuteQuery<T>(sql, pars);
        }

        /// <summary>
        /// 获取列表，多获取一条来判断是否有下一页
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="order">排序Func 倒序</param>
        /// <returns></returns>
        public List<K> GetList<T, K>(Expression<Func<T, bool>> where, int pageIndex, int pageSize, Expression<Func<T, K>> selector, Expression<Func<T, long>> order = null) where T : BaseInfo where K : SimpleInfo
        {
            return dbContextFactory.GetList<T, K>(where, pageIndex, pageSize, selector, order);
        }

        /// <summary>
        /// 获取所有记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="K"></typeparam>
        /// <param name="where"></param>
        /// <param name="selector"></param>
        /// <param name="order"></param>
        /// <param name="order">2:倒序</param>
        /// <returns></returns>
        public List<K> GetAll<T, K>(Expression<Func<T, bool>> where, Expression<Func<T, K>> selector, Expression<Func<T, long>> order = null, int sortType = 2) where T : BaseInfo where K : SimpleInfo
        {
            return dbContextFactory.GetAll<T, K>(where, selector, order, sortType);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="order"></param>
        /// <param name="sortType">2:倒序</param>
        /// <returns></returns>
        public List<T> GetAll<T>(Expression<Func<T, bool>> where, Expression<Func<T, long>> order = null, int sortType = 2) where T : BaseInfo
        {
            return dbContextFactory.GetAll<T>(where, order, sortType);
        }

        /// <summary>
        /// 获取列表 排序字段类型为 long
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="rowCount">总条数</param>
        /// <param name="order"></param>
        /// <param name="sortType">1:顺序 2：倒序</param>
        /// <returns></returns>
        public PageList<K> GetPageList<T, K>(Expression<Func<T, bool>> where, int pageIndex, int pageSize, Expression<Func<T, K>> selector, Expression<Func<T, int>> order = null, int sortType = 2) where T : BaseInfo where K : SimpleInfo
        {
            return dbContextFactory.GetPageList<T, K>(where, pageIndex, pageSize, selector, order, sortType);
        }

        public PageList<T> GetPageList<T>(Expression<Func<T, bool>> where, int pageIndex, int pageSize, Expression<Func<T, int>> order = null, int sortType = 2) where T : BaseInfo
        {
            return dbContextFactory.GetPageList<T>(where, pageIndex, pageSize, order, sortType);
        }

        /// <summary>
        /// 获取列表 排序字段类型为string
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="rowCount">总条数</param>
        /// <param name="order"></param>
        /// <param name="sortType">1:顺序 2：倒序</param>
        /// <returns></returns>
        public PageList<K> GetPageList2<T, K>(Expression<Func<T, bool>> where, int pageIndex, int pageSize, Expression<Func<T, K>> selector, Expression<Func<T, string>> order, int sortType = 2) where T : BaseInfo where K : SimpleInfo
        {
            return dbContextFactory.GetPageList2<T, K>(where, pageIndex, pageSize, selector, order, sortType);
        }


        public Dictionary<string, string> GetRequestGet()
        {
            Dictionary<string, string> sArray = new Dictionary<string, string>();

            var requestItem = _httpContextAccessor.HttpContext.Request.Query.Keys;
            foreach (var item in requestItem)
            {
                sArray.Add(item, _httpContextAccessor.HttpContext.Request.Query[item]);

            }
            return sArray;
        }

        public Dictionary<string, string> GetRequestPost()
        {
            Dictionary<string, string> sArray = new Dictionary<string, string>();

            var requestItem = Request.Form.Keys;
            foreach (string item in requestItem)
            {
                sArray.Add(item, Request.Form[item]);

            }
            return sArray;
        }

         
    }
}
